/* The file is saved in UTF-8 codepage.
 * Check: «Stereotype», Section mark-§, Copyright-©, Alpha-α, Beta-β, Smile-☺
 */
package cz.pecinovsky.english.lootp._115_;


import cz.pecinovsky.english.lootp._parents._ITrafficLight_120_124;

import cz.pecinovsky.english.lootp.manager.IMoveable;
import cz.pecinovsky.english.lootp.manager.Painter;
import cz.pecinovsky.english.lootp.manager.Rectangle;

import cz.pecinovsky.english.lootp.utility.Position;
import cz.pecinovsky.english.lootp.utility.NamedColor;
import cz.pecinovsky.english.lootp.utility.IO;


import cz.pecinovsky.english.lootp._115_.Light_120_124.Light;

////////////////////////////////////////////////////////////////////////////////
//%%+  +++++ End of ignored starting test - place for imports +++++
//%X+ xxxxx Start of the ovejumped text with declaration of the envelope xxxxx
/*******************************************************************************
 *<pre>
 * Předchozí:   oopnz._115_._116_Semafor_119
 * Následující: Prozatím není
 *
 * Projekt  020z - Komentáře
 *   + Začlenění do standardní šablony + Komentáře
 *
 * Projekt  021z - Použití this
 *   ~ V prvních dvou konstruktorech nahrazena původní těla
 *     příkazem this volajícím obecnější konstruktor
 *
 * Projekt  022z - Přetěžování
 *   + Přidány další dva konstruktory
 *   ~ Ve třetím konstruktoru nahrazeno tělo příkazem this
 *     volající přidaný obecnější konstruktor
 *
 * Projekt  Ppp
 *   + Přidáno
 *   - Odebráno
 *   ~ Změněno
 *</pre>
 */
public class TrafficLight_120_124
{    private TrafficLight_120_124() {}   static
////////////////////////////////////////////////////////////////////////////////
//%X- ----- End of the ovejumped text with declaration of the envelope -----


/*******************************************************************************
 * Instance třídy {@code TrafficLight} představují trafficLighty obdobné těm,
 * které řídí dopravu na křižovatkách.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
//%I+ <124
//public class TrafficLight implements IPaintable
//%I-
//%A+ >124
public class TrafficLight implements IMoveable
//%A-
//%A+ <0
        ,   _ITrafficLight_120_124
//%A-
{
//== CONSTANT CLASS ATTRIBUTES =================================================
//== VARIABLE CLASS ATTRIBUTES =================================================
//== STATIC CONSTRUCTOR (CLASS INITIALIZER, STATIC INICITALIZING BLOCK) ======== 
//== CONSTANT INSTANCE ATTRIBUTES ==============================================

    /** Krabice, v níž jsou umístěna světla. */
    private Rectangle box;

    /** Horní, červené light. */
    private Light redLight;

    /** Střední, žluté (oranžové) light. */
    private Light amberLight;

    /** Dolní, zelené light. */
    private Light greenLight;



//== VARIABLE INSTANCE ATTRIBUTES ==============================================
//== CLASS GETTERS AND SETTERS =================================================
//== OTHER NON-PRIVATE CLASS METHODS ===========================================

//##############################################################################
//== CONSTUCTORS AND FACTORY METHODS ===========================================

    /***************************************************************************
     * Vytvoří trafficLight implicitních rozměrů a barvy
     * umístěný v levém horním rohu plátna.
     */
    public TrafficLight()
    {
//%I+ <121
//        box        = new Rectangle(0,   0, 50, 150, NamedColor.BLACK);
//        redLight   = new Light    (0,   0, NamedColor.RED);
//        amberLight = new Light    (0,  50, NamedColor.YELLOW);
//        greenLight = new Light    (0, 100, NamedColor.GREEN);
//%I-
//%A+ >121
         this(0, 0);
//%A-
    }


    /***************************************************************************
     * Vytvoří trafficLight implicitních rozměrů a barvy
     * umístěný na zadané pozici.
     *
     * @param x  Vodorovná souřadnice
     * @param y  Svislá souřadnice
     */
    public TrafficLight(int x, int y)
    {
//%I+ <121
//        box        = new Rectangle(x, y+  0,  50, 150, NamedColor.BLACK);
//        redLight   = new Light    (x, y+  0, NamedColor.RED);
//        amberLight = new Light    (x, y+ 50, NamedColor.YELLOW);
//        greenLight = new Light    (x, y+100, NamedColor.GREEN);
//%I-
//%A+ >121
        this(x, y, NamedColor.BLACK);
//%A-
    }


    /***************************************************************************
     * Vytvoří trafficLight implicitních rozměrů s krabicí zadané barvy
     * umístěný na zadané pozici.
     *
     * @param x  Vodorovná souřadnice
     * @param y  Svislá souřadnice
     * @param boxColor  Požadovaná color box se světly
     */
    public TrafficLight(int x, int y, NamedColor boxColor)
    {
//%I+ <122
//        box        = new Rectangle(x, y+  0,  50, 150, boxColor);
//        redLight   = new Light    (x, y+  0, NamedColor.RED);
//        amberLight = new Light    (x, y+ 50, NamedColor.YELLOW);
//        greenLight = new Light    (x, y+100, NamedColor.GREEN);
//    }
//%I-
//%A+ >122
        this(x, y, 50, boxColor);
    }


    /***************************************************************************
     * Vytvoří trafficLight zadaných rozměrů s krabicí implicitní barvy
     * umístěný na zadaných souřadnicích.
     *
     * @param x  Vodorovná souřadnice
     * @param y  Svislá souřadnice
     * @param module  Šířka trafficLightu a diameter jeho světel
     */
    public TrafficLight(int x, int y, int module)
    {
        this(x, y, module, NamedColor.BLACK);
    }


    /***************************************************************************
     * Vytvoří trafficLight zadaných rozměrů s krabicí zadané barvy
     * umístěný na zadaných souřadnicích.
     *
     * @param x  Vodorovná souřadnice
     * @param y  Svislá souřadnice
     * @param module         Šířka trafficLightu a diameter jeho světel
     * @param boxColor  Požadovaná color box se světly
     */
    public TrafficLight(int x, int y, int module, NamedColor boxColor)
    {
        box = new Rectangle(x, y,  module, 3*module, boxColor);

        redLight   = new Light(x, y,              module,
                               NamedColor.RED,    NamedColor.NO);
        amberLight = new Light(x, y+  module,     module,
                               NamedColor.YELLOW, NamedColor.NO);
        greenLight = new Light(x, y+2*module,     module,
                               NamedColor.GREEN,  NamedColor.NO);
    }
//%A-



//== ABSTRACT METHODS ==========================================================
//== INSTANCE GETTERS AND SETTERS ==============================================
//%A+ >124

    // Sada přístupových metod vlastnosti: Position ******************************

    /***************************************************************************
     * Vrátí x-ovou (vodorovnou) souřadnici pozice instance.
     *
     * @return  x-ová souřadnice.
     */
    @Override
    public int getX()
    {
        return box.getX();
    }


    /***************************************************************************
     * Vrátí y-ovou (svislou) souřadnici pozice instance.
     *
     * @return  y-ová souřadnice.
     */
    @Override
    public int getY()
    {
        return box.getY();
    }

//%A-
//%A+ >125

    /***************************************************************************
     * Vrátí přepravku se svojí aktuální pozicí.
     *
     * @return Aktuální pozice světla
     */
//%A-
//%A+ <"
    @Override
//%A-
//%A+ >125
    public Position getPosition()
    {
        return new Position(getX(), getY());
    }


    /***************************************************************************
     * Nastaví novou pozici světla.
     *
     * @param p Nastavovaná pozice
     */
//%A-
//%A+ <"
    @Override
//%A-
//%A+ >125
    public void setPosition(Position p)
    {
        this.setPosition(p.x, p.y);
    }

//%A-
//%A+ >123

    /***************************************************************************
     * Nastaví novou pozici instance.
     *
     * @param x   Nová x-ová pozice instance
     * @param y   Nová y-ová pozice instance
     */
//%A-
//%A+ >124
    @Override
//%A-
//%A+ >123
    public void setPosition(int x, int y)
    {
        int module = box.getWidth();

        box.setPosition(x, y);
        redLight.setPosition(x, y);
        amberLight  .setPosition(x, y + module);
        greenLight .setPosition(x, y + 2*module);
    }

//%A-
//%A+ >124

    // Sada přístupových metod vlastnosti: Rozměr / Modul **********************

    /***************************************************************************
     * Vrátí základní délku, od níž se odvozují všechny rozměry objektu -
     * pro trafficLight je to šířka box spolu s průměrem jeho světel.
     *
     * @return Šířka box spolu s průměrem světel
     */
//%A-
//%A+ <"
    @Override
//%A-
//%A+ >124
    public int getModule()
    {
        return box.getWidth();
    }

//%A-
//%A+ >123

    /***************************************************************************
     * Nastaví nový module představující šířku box a diameter světel.
     *
     * @param module  Nově nastavovaný module
     */
//%A-
//%A+ <"
    @Override
//%A-
//%A+ >123
    public void setModule(int module)
    {
        box.setSize(module, 3*module);
        redLight.setModule (module);
        amberLight  .setModule (module);
        greenLight .setModule (module);

        int x = box.getX();
        int y = box.getY();
        amberLight  .setPosition(x, y + module);
        greenLight .setPosition(x, y + 2*module);
    }



//%A-
//== OTHER NON-PRIVATE INSTANCE METHODS ========================================

    /***************************************************************************
     * Projde se trafficLightem postupně všemi fázemi standardního cyklu, přičemž
     * počet milisekund, po něž trafficLight setrvá v každé fázi je dán velikostí
     * příslušného parametru.
     *
     * @param stop      Doba, po níž bude svítit pouze redLight
     * @param getReady Doba, po níž bude svítit redLight se žlutou
     * @param go     Doba, po níž bude svítit pouze greenLight
     * @param attention     Doba, po níž bude svítit pouze amberLight
     * @param allLightsOff       Doba, po níž budou všechny světla switchedOff
     */
//%A+ <"
    @Override
//%A-
    public void cycle(int stop, int getReady, int go, int attention, int lightsOff)
    {
        stop();         IO.pause(stop);
        getReady();    IO.pause(getReady);
        go();        IO.pause(go);
        attention();        IO.pause(attention);
        allLightsOff();       IO.pause(lightsOff);
    }


    /***************************************************************************
     * Projde se trafficLightem postupně všemi fázemi standardního cyklu, přičemž
     * se v každé fázi "zdrží" půl vteřiny.
     */
//%A+ <"
    @Override
//%A-
    public void cycle()
    {
        cycle(500, 500, 500, 500, 500);
    }


    /***************************************************************************
     * Prostřednictvím dodaného kreslítka vykreslí obraz své instance.
     *
     * @param painter Painter, které nakreslí instanci
     */
    @Override
    public void paint(Painter painter)
    {
        box.paint(painter);
        redLight.paint(painter);
        amberLight  .paint(painter);
        greenLight .paint(painter);
    }


    /***************************************************************************
     * Rozsvítí na trafficLightu žlutou a zhasne ostatní světla.
     */
//%A+ <"
    @Override
//%A-
    public void attention()
    {
        redLight.switchOff();
        amberLight  .switchOn();
        greenLight .switchOff();
    }


    /***************************************************************************
     * Rozsvítí na trafficLightu červenou a oranžovou a zhasne zelenou.
     */
//%A+ <"
    @Override
//%A-
    public void getReady()
    {
        redLight.switchOn();
        amberLight  .switchOn();
        greenLight .switchOff();
    }


    /***************************************************************************
     * Rozsvítí na trafficLightu červenou a zhasne ostatní světla.
     */
//%A+ <"
    @Override
//%A-
    public void stop()
    {
        redLight.switchOn();
        amberLight  .switchOff();
        greenLight .switchOff();
    }


    /***************************************************************************
     * Rozsvítí na trafficLightu zelenou a zhasne ostatní světla.
     */
//%A+ <"
    @Override
//%A-
    public void go()
    {
        redLight.switchOff();
        amberLight  .switchOff();
        greenLight .switchOn();
    }


    /***************************************************************************
     * Zhasne všechna světla trafficLightu.
     */
//%A+ <"
    @Override
//%A-
    public void allLightsOff()
    {
        redLight.switchOff();
        amberLight  .switchOff();
        greenLight .switchOff();
    }



//== PRIVATE AND AUXILIARY CLASS METHODS =======================================
//== PRIVATE AND AUXILIARY INSTANCE METHODS ====================================
//== EMBEDDED TYPES AND INNER CLASSES ==========================================
//== TESTING CLASSES AND METHODS ===============================================
//
//    /***************************************************************************
//     * Test method.
//     */
//    public static void test()
//    {
//        Light inst = new Light();
//    }
//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main(String[] args)  {  test();  }
    }

//%%- ---- Start of the ovejumped text with closing of the envelope ----
////////////////////////////////////////////////////////////////////////////////
//%I+ <121
//%I-

//== TESTING CLASSES AND METHODS ===============================================
//
//    /***************************************************************************
//     * Test method.
//     */
//    public static void test()
//    {
//        new TrafficLight();
//        new TrafficLight(100, 100);
//        new TrafficLight(200,  50, NamedColor.HNĚDÁ);
////        System.exit(0);
//    }
//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main(String[] args)  {  test();  }
}
